
#ifndef _TTG_STRUCTURES_ENUMERABLE_COLLECTIONS_
#define _TTG_STRUCTURES_ENUMERABLE_COLLECTIONS_
#include "Common/Definitions.h"

#include <list>
#include "Enumerators.h"
#include "Common/Structures/Objects.h"

namespace ttg
{
	namespace structures
	{
		//Represents collection, elements of which can be enumerated.
		template <class T>
		class EnumerableCollection
		{
			public:
				//Returns enumerator for current collection.
				virtual Enumerator<T> *getEnumerator() = 0;
				//Casts current collection to std::vector<T>.
				virtual std::vector<T> toVector()
				{
					Enumerator<T> *en = getEnumerator();
					std::vector<T> res = en->buildVector();
					SAFE_DELETE(en);
					return res;
				}
				//Casts current collection to std::list<T>.
				virtual std::list<T> toList()
				{
					Enumerator<T> *en = getEnumerator();
					std::list<T> res = en->buildList();
					SAFE_DELETE(en);
					return res;
				}
				//For descendants only.
				virtual ~EnumerableCollection()
				{ /*nothing*/ }
		};
	}
}

namespace ttg_internal
{
	namespace structures
	{
		//Wraps existen STL collection.
		template <class T, class StlType>
		class EnumerableCollection_StlWrapper :public ttg::structures::EnumerableCollection<T>
		{
			private:
				ttg::structures::ReleasableWrapper<StlType> stl_collection;
			public:
				//Creates wrapper for the required collection.
				inline EnumerableCollection_StlWrapper
					(ttg::structures::ReleasableWrapper<StlType> &stl_collection)
				{ this->stl_collection = stl_collection; }
				//EnumerableCollection member.
				virtual ttg::structures::Enumerator<T> *getEnumerator()
				{
					return new ttg::structures::StlEnumerator<T, StlType::iterator>
						(stl_collection.get().begin(), stl_collection.get().end());
				}
		};
	}
}

#endif
